import base64
import pickle
from django.shortcuts import render
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView

from goods.models import SKU
from . import serializers


class CartView(GenericAPIView):
    serializer_class = serializers.CartSerializers

    # 重写方法,让未登录用户也能访问该视图
    def perform_authentication(self, request):
        pass

    def post(self,request):

        dict_data = request.data

        serializer = self.get_serializer(data = dict_data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get("sku_id")

        count = serializer.data.get("count")
        selected = serializer.data.get("selected" , True)

        try:
            user = request.user
        except Exception as e:
            user =None

        if user and request.user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            redis_conn.hincrby("cart_%s" %user.id ,sku_id,count)

            if selected:
                redis_conn.sadd("cart_selected_%s" % user.id , sku_id)

            return Response(serializer.data)

        else:
            cookie_cart = request.COOKIES.get("cart")

            cookie_dict = {}

            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            if sku_id in cookie_dict:
                count +=cookie_dict[sku_id].get('count',0)

            cookie_dict[sku_id] = {
                "count":count,
                "selected" : selected
            }

            response = Response(status=200)

            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()

            response.set_cookie("cart",cookie_cart)
            return response

    def get(self, request):
        # 1,获取用户数据
        try:
            user = request.user
        except Exception as e:
            user = None

        # 2,判断用户登陆状态
        if user and request.user.is_authenticated:
            # 1,获取redis中用户购物车数据
            redis_conn = get_redis_connection("cart")
            redis_cart_dict = redis_conn.hgetall("cart_%s" % user.id)
            redis_cart_selcted_list = redis_conn.smembers("cart_selected_%s" % user.id)

            # 2,数据拼接
            sku_list = []
            for sku_id, count in redis_cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "selected": sku_id in redis_cart_selcted_list,
                    "default_image_url": sku.default_image_url,
                    "name": sku.name,
                    "price": sku.price,
                    "count": int(count),
                    "id" : sku.id
                }
                sku_list.append(sku_dict)

            # 3,返回响应
            return Response(sku_list)
        else:
            cookie_cart = request.COOKIES.get("cart")

            # 4,转换成字典
            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            # 5,拼接数据
            sku_list = []
            for sku_id, count_selected in cookie_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "selected": count_selected["selected"],
                    "default_image_url": sku.default_image_url,
                    "name": sku.name,
                    "price": sku.price,
                    "count": int(count_selected["count"]),
                    "id" :sku.id
                }
                sku_list.append(sku_dict)

            # 6,返回响应
            return Response(sku_list)

    def put(self, request):
        dict_data = request.data

        serializer = self.get_serializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get("sku_id")

        count = serializer.data.get("count")
        selected = serializer.data.get("selected")

        try:
            user = request.user
        except Exception as e:
            user = None

        if user and request.user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            redis_conn.hset("cart_%s" % user.id, sku_id, count)

            if selected:
                redis_conn.sadd("cart_selected_%s" % user.id, sku_id)
            else:
                redis_conn.srem("cart_selected_%s" % user.id, sku_id)


            return Response(serializer.data)
        else:

            cookie_cart = request.COOKIES.get("cart")

            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            cookie_dict[sku_id] = {
                "count": count,
                "selected": selected
            }

            response = Response(serializer.data)
            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie("cart", cookie_cart)
            return response

    def delete(self, request):
        dict_data = request.data

        serializer = serializers.CartDeleteSerializers(data =dict_data)

        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get("sku_id")

        try:
            user = request.user

        except:
            user = None

        if user and request.user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            redis_conn.hdel("cart_%s" % user.id,sku_id)
            redis_conn.hdel("cart_selectes_%s" % user.id,sku_id)

            return Response(status=status.HTTP_204_NO_CONTENT)

        else:

            cookie_cart = request.COOKIES.get("cart")

            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            if sku_id in cookie_dict:
                del cookie_dict[sku_id]

            response = Response(status=status.HTTP_204_NO_CONTENT)
            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie("cart", cookie_cart)
            return response